package service;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.*;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

public class UploadServlet extends HttpServlet {
    private static final long serialVersionUID = -7799504651510179665L;
    private DiskFileItemFactory factory = new DiskFileItemFactory();
    private RequestDispatcher dispatcher;

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        dispatcher = req.getRequestDispatcher("upload.jsp");
        // 如果请求对象的编码类型是multipart/form-data
        if (ServletFileUpload.isMultipartContent(req)) {
            // 设置阈值，在此阈值之上的上传内容将被存储在磁盘上（默认值为10240）
            factory.setSizeThreshold(16384);
            // 设置临时文件的存储目录
            File tempDirectory = new File(req.getServletContext().getRealPath("/"));
            factory.setRepository(tempDirectory);
            // 以指定的文件项工厂构造一个ServletFileUpload对象
            ServletFileUpload upload = new ServletFileUpload(factory);
            // 设置单个上传的文件的最大长度
            upload.setFileSizeMax(134217728);
            // 定义允许上传的文件扩展
            String[] array = { ".mp3", ".mp4", ".wmv", ".mkv", ".txt", ".jpg", ".png", ".zip", ".rar", ".7z", ".tar", ".gz", ".pdf", ".gif" };
            List<String> extensions = Arrays.asList(array);
            // 解析请求对象，将所有请求参数解析为由FileItem元素构成的有序集合
            List<FileItem> items;
            try {
                items = upload.parseRequest(req);
                for (FileItem item : items) {
                    // 如果当前项不是表单普通项，即文件输入项（类型为file的表单元素input）
                    if (!item.isFormField()) {
                        String filename = item.getName();
                        int index = filename.lastIndexOf(".");
                        // 如果文件名为空或者文件没有扩展名
                        if (filename.trim().equals("") || index == -1) {
                            req.setAttribute("error", "文件名非法");
                            dispatcher.forward(req, resp);
                            return;
                        }
                        String fileType = filename.substring(index);
                        if (!extensions.contains(fileType)) {
                            req.setAttribute("error", "不允许上传扩展名为" + fileType.substring(1) + "的文件");
                            dispatcher.forward(req, resp);
                            return;
                        }
                        String directory = req.getServletContext().getRealPath("/uploaded/");
                        filename = directory + filename.substring(0, index) + "_" + Calendar.getInstance().getTimeInMillis() + fileType;
                        File uploadFile = new File(filename);
                        // 一种将上传的项目写入磁盘的便捷方法（注：也可以获取FileItem对象的输入流，通过流的方式上传文件）
                        item.write(uploadFile);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            req.setAttribute("error", "请求对象的编码类型不是multipart/form-data");
            dispatcher.forward(req, resp);
        }
        resp.sendRedirect("upload.jsp");
    }
}
